home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / applic / ntp / kent.shar / fastdemo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-29  |  35.7 KB  |  1,044 lines

  1. /* fastdemo.c: jl 5 May 1986: demonstrate DES in various modes, using */
  2. /* optimized DES version */
  3. /* changes 2 June 1986: */
  4. /* use Dan Hoey's IP, IP-1 optimization */
  5.  
  6. /* define TIMEONLY to time DES cycles rather than run ordinary demo */
  7. /* timing data on C/70, (compiled -O) with 500 iterations */
  8. /* (each iteration is an encrypt+decrypt) */
  9. /* without HOEYOPT: typical DES op is about 7.825 msec (470 ticks/1000 opns) */
  10. /* with HOEYOPT: typical DES op is about 7.425 msec (445 ticks/1000 opns) */
  11. /* this compares with VAX timing of a slightly different version, */
  12. /* (pre-HOEYOPT) of 2.6 ms/cycle */
  13.  
  14. /* Additional timing data, from David Balenson at NBS, March 1988 */
  15. /* I initially tried it on our VAX 11/750 and SUN 3/160 (both */
  16. /* running UNIX BSD 4.2) and acheived measurements of 15.3Kbps on the */
  17. /* VAX and 54.1Kbps(!!!) on the SUN.  It also compiled and ran successfully */
  18. /* under PC-DOS using the Computer Innovations C86 C compiler.  I added */
  19. /* DOS-based timing routines in place of your UNIX routines and got times */
  20. /* of 8.4Kbps on an 8MHz AT and 10.2Kbps on a PS/2-50. */
  21.  
  22. #include        <stdio.h>
  23. #include        <ctype.h>
  24.  
  25. #define FALSE   0
  26. #define TRUE    1
  27.  
  28. #define ECB     1
  29. #define CBC     ECB+1
  30. #define OFB     CBC+1
  31. #define CFB     OFB+1
  32.  
  33. /* Dan Hoey (hoey@nrl-aic)'s optimization, per 16 May 1986 netmail */
  34. /* Exchange bits of A selected by mask M with bits of B selected by */
  35. /* mask (M << S). TMP is a temporary. */
  36. #define EXSHMSK(A,M,B,S,TMP)    \
  37.     TMP = ((B >> S) ^ A) & M;   \
  38.     A ^= TMP;                   \
  39.     TMP <<= S;                  \
  40.     B ^= TMP
  41.  
  42. /* tables to describe permutations, per NBS FIPS */
  43.  
  44. static int pc1c [] =
  45.     { 57, 49, 41, 33, 25, 17, 9,
  46.       1, 58, 50, 42, 34, 26, 18,
  47.       10, 2, 59, 51, 43, 35, 27,
  48.       19, 11, 3, 60, 52, 44, 36 };
  49.  
  50. static int pc1d [] =
  51.     { 63, 55, 47, 39, 31, 23, 15,
  52.       7, 62, 54, 46, 38, 30, 22,
  53.       14, 6, 61, 53, 45, 37, 29,
  54.       21, 13, 5, 28, 20, 12, 4 };
  55.  
  56. static int shiftsked []=
  57.     { 1, 1, 2, 2, 2, 2, 2, 2,
  58.       1, 2, 2, 2, 2, 2, 2, 1 };
  59.  
  60. #ifdef  TIMEONLY
  61. /* facilities for timing */
  62. struct tbuffer
  63. {
  64.   long proc_utime;
  65.   long proc_stime;
  66.   long child_utime;
  67.   long child_stime;
  68. };
  69. struct tbuffer t_before;
  70. struct tbuffer t_after;
  71. #endif
  72.  
  73. long snop [8] [64] = {
  74. 0X808200L,0X0L,0X8000L,0X808202L,
  75. 0X808002L,0X8202L,0X2L,0X8000L,
  76. 0X200L,0X808200L,0X808202L,0X200L,
  77. 0X800202L,0X808002L,0X800000L,0X2L,
  78. 0X202L,0X800200L,0X800200L,0X8200L,
  79. 0X8200L,0X808000L,0X808000L,0X800202L,
  80. 0X8002L,0X800002L,0X800002L,0X8002L,
  81. 0X0L,0X202L,0X8202L,0X800000L,
  82. 0X8000L,0X808202L,0X2L,0X808000L,
  83. 0X808200L,0X800000L,0X800000L,0X200L,
  84. 0X808002L,0X8000L,0X8200L,0X800002L,
  85. 0X200L,0X2L,0X800202L,0X8202L,
  86. 0X808202L,0X8002L,0X808000L,0X800202L,
  87. 0X800002L,0X202L,0X8202L,0X808200L,
  88. 0X202L,0X800200L,0X800200L,0X0L,
  89. 0X8002L,0X8200L,0X0L,0X808002L,
  90.  
  91. 0X104L,0X4010100L,0X0L,0X4010004L,
  92. 0X4000100L,0X0L,0X10104L,0X4000100L,
  93. 0X10004L,0X4000004L,0X4000004L,0X10000L,
  94. 0X4010104L,0X10004L,0X4010000L,0X104L,
  95. 0X4000000L,0X4L,0X4010100L,0X100L,
  96. 0X10100L,0X4010000L,0X4010004L,0X10104L,
  97. 0X4000104L,0X10100L,0X10000L,0X4000104L,
  98. 0X4L,0X4010104L,0X100L,0X4000000L,
  99. 0X4010100L,0X4000000L,0X10004L,0X104L,
  100. 0X10000L,0X4010100L,0X4000100L,0X0L,
  101. 0X100L,0X10004L,0X4010104L,0X4000100L,
  102. 0X4000004L,0X100L,0X0L,0X4010004L,
  103. 0X4000104L,0X10000L,0X4000000L,0X4010104L,
  104. 0X4L,0X10104L,0X10100L,0X4000004L,
  105. 0X4010000L,0X4000104L,0X104L,0X4010000L,
  106. 0X10104L,0X4L,0X4010004L,0X10100L,
  107.  
  108. 0X80L,0X1040080L,0X1040000L,0X21000080L,
  109. 0X40000L,0X80L,0X20000000L,0X1040000L,
  110. 0X20040080L,0X40000L,0X1000080L,0X20040080L,
  111. 0X21000080L,0X21040000L,0X40080L,0X20000000L,
  112. 0X1000000L,0X20040000L,0X20040000L,0X0L,
  113. 0X20000080L,0X21040080L,0X21040080L,0X1000080L,
  114. 0X21040000L,0X20000080L,0X0L,0X21000000L,
  115. 0X1040080L,0X1000000L,0X21000000L,0X40080L,
  116. 0X40000L,0X21000080L,0X80L,0X1000000L,
  117. 0X20000000L,0X1040000L,0X21000080L,0X20040080L,
  118. 0X1000080L,0X20000000L,0X21040000L,0X1040080L,
  119. 0X20040080L,0X80L,0X1000000L,0X21040000L,
  120. 0X21040080L,0X40080L,0X21000000L,0X21040080L,
  121. 0X1040000L,0X0L,0X20040000L,0X21000000L,
  122. 0X40080L,0X1000080L,0X20000080L,0X40000L,
  123. 0X0L,0X20040000L,0X1040080L,0X20000080L,
  124.  
  125. 0X100000L,0X2100001L,0X2000401L,0X0L,
  126. 0X400L,0X2000401L,0X100401L,0X2100400L,
  127. 0X2100401L,0X100000L,0X0L,0X2000001L,
  128. 0X1L,0X2000000L,0X2100001L,0X401L,
  129. 0X2000400L,0X100401L,0X100001L,0X2000400L,
  130. 0X2000001L,0X2100000L,0X2100400L,0X100001L,
  131. 0X2100000L,0X400L,0X401L,0X2100401L,
  132. 0X100400L,0X1L,0X2000000L,0X100400L,
  133. 0X2000000L,0X100400L,0X100000L,0X2000401L,
  134. 0X2000401L,0X2100001L,0X2100001L,0X1L,
  135. 0X100001L,0X2000000L,0X2000400L,0X100000L,
  136. 0X2100400L,0X401L,0X100401L,0X2100400L,
  137. 0X401L,0X2000001L,0X2100401L,0X2100000L,
  138. 0X100400L,0X0L,0X1L,0X2100401L,
  139. 0X0L,0X100401L,0X2100000L,0X400L,
  140. 0X2000001L,0X2000400L,0X400L,0X100001L,
  141.  
  142. 0X40084010L,0X40004000L,0X4000L,0X84010L,
  143. 0X80000L,0X10L,0X40080010L,0X40004010L,
  144. 0X40000010L,0X40084010L,0X40084000L,0X40000000L,
  145. 0X40004000L,0X80000L,0X10L,0X40080010L,
  146. 0X84000L,0X80010L,0X40004010L,0X0L,
  147. 0X40000000L,0X4000L,0X84010L,0X40080000L,
  148. 0X80010L,0X40000010L,0X0L,0X84000L,
  149. 0X4010L,0X40084000L,0X40080000L,0X4010L,
  150. 0X0L,0X84010L,0X40080010L,0X80000L,
  151. 0X40004010L,0X40080000L,0X40084000L,0X4000L,
  152. 0X40080000L,0X40004000L,0X10L,0X40084010L,
  153. 0X84010L,0X10L,0X4000L,0X40000000L,
  154. 0X4010L,0X40084000L,0X80000L,0X40000010L,
  155. 0X80010L,0X40004010L,0X40000010L,0X80010L,
  156. 0X84000L,0X0L,0X40004000L,0X4010L,
  157. 0X40000000L,0X40080010L,0X40084010L,0X84000L,
  158.  
  159. 0X80401000L,0X80001040L,0X80001040L,0X40L,
  160. 0X401040L,0X80400040L,0X80400000L,0X80001000L,
  161. 0X0L,0X401000L,0X401000L,0X80401040L,
  162. 0X80000040L,0X0L,0X400040L,0X80400000L,
  163. 0X80000000L,0X1000L,0X400000L,0X80401000L,
  164. 0X40L,0X400000L,0X80001000L,0X1040L,
  165. 0X80400040L,0X80000000L,0X1040L,0X400040L,
  166. 0X1000L,0X401040L,0X80401040L,0X80000040L,
  167. 0X400040L,0X80400000L,0X401000L,0X80401040L,
  168. 0X80000040L,0X0L,0X0L,0X401000L,
  169. 0X1040L,0X400040L,0X80400040L,0X80000000L,
  170. 0X80401000L,0X80001040L,0X80001040L,0X40L,
  171. 0X80401040L,0X80000040L,0X80000000L,0X1000L,
  172. 0X80400000L,0X80001000L,0X401040L,0X80400040L,
  173. 0X80001000L,0X1040L,0X400000L,0X80401000L,
  174. 0X40L,0X400000L,0X1000L,0X401040L,
  175.  
  176. 0X10000008L,0X10200000L,0X2000L,0X10202008L,
  177. 0X10200000L,0X8L,0X10202008L,0X200000L,
  178. 0X10002000L,0X202008L,0X200000L,0X10000008L,
  179. 0X200008L,0X10002000L,0X10000000L,0X2008L,
  180. 0X0L,0X200008L,0X10002008L,0X2000L,
  181. 0X202000L,0X10002008L,0X8L,0X10200008L,
  182. 0X10200008L,0X0L,0X202008L,0X10202000L,
  183. 0X2008L,0X202000L,0X10202000L,0X10000000L,
  184. 0X10002000L,0X8L,0X10200008L,0X202000L,
  185. 0X10202008L,0X200000L,0X2008L,0X10000008L,
  186. 0X200000L,0X10002000L,0X10000000L,0X2008L,
  187. 0X10000008L,0X10202008L,0X202000L,0X10200000L,
  188. 0X202008L,0X10202000L,0X0L,0X10200008L,
  189. 0X8L,0X2000L,0X10200000L,0X202008L,
  190. 0X2000L,0X200008L,0X10002008L,0X0L,
  191. 0X10202000L,0X10000000L,0X200008L,0X10002008L,
  192.  
  193. 0X8000820L,0X800L,0X20000L,0X8020820L,
  194. 0X8000000L,0X8000820L,0X20L,0X8000000L,
  195. 0X20020L,0X8020000L,0X8020820L,0X20800L,
  196. 0X8020800L,0X20820L,0X800L,0X20L,
  197. 0X8020000L,0X8000020L,0X8000800L,0X820L,
  198. 0X20800L,0X20020L,0X8020020L,0X8020800L,
  199. 0X820L,0X0L,0X0L,0X8020020L,
  200. 0X8000020L,0X8000800L,0X20820L,0X20000L,
  201. 0X20820L,0X20000L,0X8020800L,0X800L,
  202. 0X20L,0X8020020L,0X800L,0X20820L,
  203. 0X8000800L,0X20L,0X8000020L,0X8020000L,
  204. 0X8020020L,0X8000000L,0X20000L,0X8000820L,
  205. 0X0L,0X8020820L,0X20020L,0X8000020L,
  206. 0X8020000L,0X8000800L,0X8000820L,0X0L,
  207. 0X8020820L,0X20800L,0X20800L,0X820L,
  208. 0X820L,0X20020L,0X8000000L,0X8020800L 
  209. };
  210.  
  211. long pc2otab [8] [128] = {
  212. 0X0L,0X10L,0X4000L,0X4010L,0X40000L,0X40010L,0X44000L,0X44010L,
  213. 0X100L,0X110L,0X4100L,0X4110L,0X40100L,0X40110L,0X44100L,0X44110L,
  214. 0X20000L,0X20010L,0X24000L,0X24010L,0X60000L,0X60010L,0X64000L,0X64010L,
  215. 0X20100L,0X20110L,0X24100L,0X24110L,0X60100L,0X60110L,0X64100L,0X64110L,
  216. 0X1L,0X11L,0X4001L,0X4011L,0X40001L,0X40011L,0X44001L,0X44011L,
  217. 0X101L,0X111L,0X4101L,0X4111L,0X40101L,0X40111L,0X44101L,0X44111L,
  218. 0X20001L,0X20011L,0X24001L,0X24011L,0X60001L,0X60011L,0X64001L,0X64011L,
  219. 0X20101L,0X20111L,0X24101L,0X24111L,0X60101L,0X60111L,0X64101L,0X64111L,
  220. 0X80000L,0X80010L,0X84000L,0X84010L,0XC0000L,0XC0010L,0XC4000L,0XC4010L,
  221. 0X80100L,0X80110L,0X84100L,0X84110L,0XC0100L,0XC0110L,0XC4100L,0XC4110L,
  222. 0XA0000L,0XA0010L,0XA4000L,0XA4010L,0XE0000L,0XE0010L,0XE4000L,0XE4010L,
  223. 0XA0100L,0XA0110L,0XA4100L,0XA4110L,0XE0100L,0XE0110L,0XE4100L,0XE4110L,
  224. 0X80001L,0X80011L,0X84001L,0X84011L,0XC0001L,0XC0011L,0XC4001L,0XC4011L,
  225. 0X80101L,0X80111L,0X84101L,0X84111L,0XC0101L,0XC0111L,0XC4101L,0XC4111L,
  226. 0XA0001L,0XA0011L,0XA4001L,0XA4011L,0XE0001L,0XE0011L,0XE4001L,0XE4011L,
  227. 0XA0101L,0XA0111L,0XA4101L,0XA4111L,0XE0101L,0XE0111L,0XE4101L,0XE4111L,
  228.  
  229. 0X0L,0X800000L,0X2L,0X800002L,0X200L,0X800200L,0X202L,0X800202L,
  230. 0X200000L,0XA00000L,0X200002L,0XA00002L,0X200200L,0XA00200L,0X200202L,0XA00202L,
  231. 0X1000L,0X801000L,0X1002L,0X801002L,0X1200L,0X801200L,0X1202L,0X801202L,
  232. 0X201000L,0XA01000L,0X201002L,0XA01002L,0X201200L,0XA01200L,0X201202L,0XA01202L,
  233. 0X0L,0X800000L,0X2L,0X800002L,0X200L,0X800200L,0X202L,0X800202L,
  234. 0X200000L,0XA00000L,0X200002L,0XA00002L,0X200200L,0XA00200L,0X200202L,0XA00202L,
  235. 0X1000L,0X801000L,0X1002L,0X801002L,0X1200L,0X801200L,0X1202L,0X801202L,
  236. 0X201000L,0XA01000L,0X201002L,0XA01002L,0X201200L,0XA01200L,0X201202L,0XA01202L,
  237. 0X40L,0X800040L,0X42L,0X800042L,0X240L,0X800240L,0X242L,0X800242L,
  238. 0X200040L,0XA00040L,0X200042L,0XA00042L,0X200240L,0XA00240L,0X200242L,0XA00242L,
  239. 0X1040L,0X801040L,0X1042L,0X801042L,0X1240L,0X801240L,0X1242L,0X801242L,
  240. 0X201040L,0XA01040L,0X201042L,0XA01042L,0X201240L,0XA01240L,0X201242L,0XA01242L,
  241. 0X40L,0X800040L,0X42L,0X800042L,0X240L,0X800240L,0X242L,0X800242L,
  242. 0X200040L,0XA00040L,0X200042L,0XA00042L,0X200240L,0XA00240L,0X200242L,0XA00242L,
  243. 0X1040L,0X801040L,0X1042L,0X801042L,0X1240L,0X801240L,0X1242L,0X801242L,
  244. 0X201040L,0XA01040L,0X201042L,0XA01042L,0X201240L,0XA01240L,0X201242L,0XA01242L,
  245.  
  246. 0X0L,0X2000L,0X4L,0X2004L,0X400L,0X2400L,0X404L,0X2404L,
  247. 0X0L,0X2000L,0X4L,0X2004L,0X400L,0X2400L,0X404L,0X2404L,
  248. 0X400000L,0X402000L,0X400004L,0X402004L,0X400400L,0X402400L,0X400404L,0X402404L,
  249. 0X400000L,0X402000L,0X400004L,0X402004L,0X400400L,0X402400L,0X400404L,0X402404L,
  250. 0X20L,0X2020L,0X24L,0X2024L,0X420L,0X2420L,0X424L,0X2424L,
  251. 0X20L,0X2020L,0X24L,0X2024L,0X420L,0X2420L,0X424L,0X2424L,
  252. 0X400020L,0X402020L,0X400024L,0X402024L,0X400420L,0X402420L,0X400424L,0X402424L,
  253. 0X400020L,0X402020L,0X400024L,0X402024L,0X400420L,0X402420L,0X400424L,0X402424L,
  254. 0X8000L,0XA000L,0X8004L,0XA004L,0X8400L,0XA400L,0X8404L,0XA404L,
  255. 0X8000L,0XA000L,0X8004L,0XA004L,0X8400L,0XA400L,0X8404L,0XA404L,
  256. 0X408000L,0X40A000L,0X408004L,0X40A004L,0X408400L,0X40A400L,0X408404L,0X40A404L,
  257. 0X408000L,0X40A000L,0X408004L,0X40A004L,0X408400L,0X40A400L,0X408404L,0X40A404L,
  258. 0X8020L,0XA020L,0X8024L,0XA024L,0X8420L,0XA420L,0X8424L,0XA424L,
  259. 0X8020L,0XA020L,0X8024L,0XA024L,0X8420L,0XA420L,0X8424L,0XA424L,
  260. 0X408020L,0X40A020L,0X408024L,0X40A024L,0X408420L,0X40A420L,0X408424L,0X40A424L,
  261. 0X408020L,0X40A020L,0X408024L,0X40A024L,0X408420L,0X40A420L,0X408424L,0X40A424L,
  262.  
  263. 0X0L,0X10000L,0X8L,0X10008L,0X80L,0X10080L,0X88L,0X10088L,
  264. 0X0L,0X10000L,0X8L,0X10008L,0X80L,0X10080L,0X88L,0X10088L,
  265. 0X100000L,0X110000L,0X100008L,0X110008L,0X100080L,0X110080L,0X100088L,0X110088L,
  266. 0X100000L,0X110000L,0X100008L,0X110008L,0X100080L,0X110080L,0X100088L,0X110088L,
  267. 0X800L,0X10800L,0X808L,0X10808L,0X880L,0X10880L,0X888L,0X10888L,
  268. 0X800L,0X10800L,0X808L,0X10808L,0X880L,0X10880L,0X888L,0X10888L,
  269. 0X100800L,0X110800L,0X100808L,0X110808L,0X100880L,0X110880L,0X100888L,0X110888L,
  270. 0X100800L,0X110800L,0X100808L,0X110808L,0X100880L,0X110880L,0X100888L,0X110888L,
  271. 0X0L,0X10000L,0X8L,0X10008L,0X80L,0X10080L,0X88L,0X10088L,
  272. 0X0L,0X10000L,0X8L,0X10008L,0X80L,0X10080L,0X88L,0X10088L,
  273. 0X100000L,0X110000L,0X100008L,0X110008L,0X100080L,0X110080L,0X100088L,0X110088L,
  274. 0X100000L,0X110000L,0X100008L,0X110008L,0X100080L,0X110080L,0X100088L,0X110088L,
  275. 0X800L,0X10800L,0X808L,0X10808L,0X880L,0X10880L,0X888L,0X10888L,
  276. 0X800L,0X10800L,0X808L,0X10808L,0X880L,0X10880L,0X888L,0X10888L,
  277. 0X100800L,0X110800L,0X100808L,0X110808L,0X100880L,0X110880L,0X100888L,0X110888L,
  278. 0X100800L,0X110800L,0X100808L,0X110808L,0X100880L,0X110880L,0X100888L,0X110888L,
  279.  
  280. 0X0L,0X0L,0X80L,0X80L,0X2000L,0X2000L,0X2080L,0X2080L,
  281. 0X1L,0X1L,0X81L,0X81L,0X2001L,0X2001L,0X2081L,0X2081L,
  282. 0X200000L,0X200000L,0X200080L,0X200080L,0X202000L,0X202000L,0X202080L,0X202080L,
  283. 0X200001L,0X200001L,0X200081L,0X200081L,0X202001L,0X202001L,0X202081L,0X202081L,
  284. 0X20000L,0X20000L,0X20080L,0X20080L,0X22000L,0X22000L,0X22080L,0X22080L,
  285. 0X20001L,0X20001L,0X20081L,0X20081L,0X22001L,0X22001L,0X22081L,0X22081L,
  286. 0X220000L,0X220000L,0X220080L,0X220080L,0X222000L,0X222000L,0X222080L,0X222080L,
  287. 0X220001L,0X220001L,0X220081L,0X220081L,0X222001L,0X222001L,0X222081L,0X222081L,
  288. 0X2L,0X2L,0X82L,0X82L,0X2002L,0X2002L,0X2082L,0X2082L,
  289. 0X3L,0X3L,0X83L,0X83L,0X2003L,0X2003L,0X2083L,0X2083L,
  290. 0X200002L,0X200002L,0X200082L,0X200082L,0X202002L,0X202002L,0X202082L,0X202082L,
  291. 0X200003L,0X200003L,0X200083L,0X200083L,0X202003L,0X202003L,0X202083L,0X202083L,
  292. 0X20002L,0X20002L,0X20082L,0X20082L,0X22002L,0X22002L,0X22082L,0X22082L,
  293. 0X20003L,0X20003L,0X20083L,0X20083L,0X22003L,0X22003L,0X22083L,0X22083L,
  294. 0X220002L,0X220002L,0X220082L,0X220082L,0X222002L,0X222002L,0X222082L,0X222082L,
  295. 0X220003L,0X220003L,0X220083L,0X220083L,0X222003L,0X222003L,0X222083L,0X222083L,
  296.  
  297. 0X0L,0X10L,0X800000L,0X800010L,0X10000L,0X10010L,0X810000L,0X810010L,
  298. 0X200L,0X210L,0X800200L,0X800210L,0X10200L,0X10210L,0X810200L,0X810210L,
  299. 0X0L,0X10L,0X800000L,0X800010L,0X10000L,0X10010L,0X810000L,0X810010L,
  300. 0X200L,0X210L,0X800200L,0X800210L,0X10200L,0X10210L,0X810200L,0X810210L,
  301. 0X100000L,0X100010L,0X900000L,0X900010L,0X110000L,0X110010L,0X910000L,0X910010L,
  302. 0X100200L,0X100210L,0X900200L,0X900210L,0X110200L,0X110210L,0X910200L,0X910210L,
  303. 0X100000L,0X100010L,0X900000L,0X900010L,0X110000L,0X110010L,0X910000L,0X910010L,
  304. 0X100200L,0X100210L,0X900200L,0X900210L,0X110200L,0X110210L,0X910200L,0X910210L,
  305. 0X4L,0X14L,0X800004L,0X800014L,0X10004L,0X10014L,0X810004L,0X810014L,
  306. 0X204L,0X214L,0X800204L,0X800214L,0X10204L,0X10214L,0X810204L,0X810214L,
  307. 0X4L,0X14L,0X800004L,0X800014L,0X10004L,0X10014L,0X810004L,0X810014L,
  308. 0X204L,0X214L,0X800204L,0X800214L,0X10204L,0X10214L,0X810204L,0X810214L,
  309. 0X100004L,0X100014L,0X900004L,0X900014L,0X110004L,0X110014L,0X910004L,0X910014L,
  310. 0X100204L,0X100214L,0X900204L,0X900214L,0X110204L,0X110214L,0X910204L,0X910214L,
  311. 0X100004L,0X100014L,0X900004L,0X900014L,0X110004L,0X110014L,0X910004L,0X910014L,
  312. 0X100204L,0X100214L,0X900204L,0X900214L,0X110204L,0X110214L,0X910204L,0X910214L,
  313.  
  314. 0X0L,0X400L,0X1000L,0X1400L,0X80000L,0X80400L,0X81000L,0X81400L,
  315. 0X20L,0X420L,0X1020L,0X1420L,0X80020L,0X80420L,0X81020L,0X81420L,
  316. 0X4000L,0X4400L,0X5000L,0X5400L,0X84000L,0X84400L,0X85000L,0X85400L,
  317. 0X4020L,0X4420L,0X5020L,0X5420L,0X84020L,0X84420L,0X85020L,0X85420L,
  318. 0X800L,0XC00L,0X1800L,0X1C00L,0X80800L,0X80C00L,0X81800L,0X81C00L,
  319. 0X820L,0XC20L,0X1820L,0X1C20L,0X80820L,0X80C20L,0X81820L,0X81C20L,
  320. 0X4800L,0X4C00L,0X5800L,0X5C00L,0X84800L,0X84C00L,0X85800L,0X85C00L,
  321. 0X4820L,0X4C20L,0X5820L,0X5C20L,0X84820L,0X84C20L,0X85820L,0X85C20L,
  322. 0X0L,0X400L,0X1000L,0X1400L,0X80000L,0X80400L,0X81000L,0X81400L,
  323. 0X20L,0X420L,0X1020L,0X1420L,0X80020L,0X80420L,0X81020L,0X81420L,
  324. 0X4000L,0X4400L,0X5000L,0X5400L,0X84000L,0X84400L,0X85000L,0X85400L,
  325. 0X4020L,0X4420L,0X5020L,0X5420L,0X84020L,0X84420L,0X85020L,0X85420L,
  326. 0X800L,0XC00L,0X1800L,0X1C00L,0X80800L,0X80C00L,0X81800L,0X81C00L,
  327. 0X820L,0XC20L,0X1820L,0X1C20L,0X80820L,0X80C20L,0X81820L,0X81C20L,
  328. 0X4800L,0X4C00L,0X5800L,0X5C00L,0X84800L,0X84C00L,0X85800L,0X85C00L,
  329. 0X4820L,0X4C20L,0X5820L,0X5C20L,0X84820L,0X84C20L,0X85820L,0X85C20L,
  330.  
  331. 0X0L,0X100L,0X40000L,0X40100L,0X0L,0X100L,0X40000L,0X40100L,
  332. 0X40L,0X140L,0X40040L,0X40140L,0X40L,0X140L,0X40040L,0X40140L,
  333. 0X400000L,0X400100L,0X440000L,0X440100L,0X400000L,0X400100L,0X440000L,0X440100L,
  334. 0X400040L,0X400140L,0X440040L,0X440140L,0X400040L,0X400140L,0X440040L,0X440140L,
  335. 0X8000L,0X8100L,0X48000L,0X48100L,0X8000L,0X8100L,0X48000L,0X48100L,
  336. 0X8040L,0X8140L,0X48040L,0X48140L,0X8040L,0X8140L,0X48040L,0X48140L,
  337. 0X408000L,0X408100L,0X448000L,0X448100L,0X408000L,0X408100L,0X448000L,0X448100L,
  338. 0X408040L,0X408140L,0X448040L,0X448140L,0X408040L,0X408140L,0X448040L,0X448140L,
  339. 0X8L,0X108L,0X40008L,0X40108L,0X8L,0X108L,0X40008L,0X40108L,
  340. 0X48L,0X148L,0X40048L,0X40148L,0X48L,0X148L,0X40048L,0X40148L,
  341. 0X400008L,0X400108L,0X440008L,0X440108L,0X400008L,0X400108L,0X440008L,0X440108L,
  342. 0X400048L,0X400148L,0X440048L,0X440148L,0X400048L,0X400148L,0X440048L,0X440148L,
  343. 0X8008L,0X8108L,0X48008L,0X48108L,0X8008L,0X8108L,0X48008L,0X48108L,
  344. 0X8048L,0X8148L,0X48048L,0X48148L,0X8048L,0X8148L,0X48048L,0X48148L,
  345. 0X408008L,0X408108L,0X448008L,0X448108L,0X408008L,0X408108L,0X448008L,0X448108L,
  346. 0X408048L,0X408148L,0X448048L,0X448148L,0X408048L,0X408148L,0X448048L,0X448148L 
  347. };
  348.  
  349. /* --- some bit manipulation primitives --- */
  350.  
  351. /* g_keybit -- extract bit bnum from the key in inkey */
  352. #define g_keybit(bnum) (01 & (inkey [bnum/8] >> (8 - (bnum%8))))
  353.  
  354. long    lrot28 (lval)
  355. /* do left rotate of 28 bit quantity */
  356. long    lval;
  357. {
  358.   lval <<= 1;
  359.   if (0X10000000L & lval) lval++;
  360.   lval &= 0XFFFFFFFL;
  361.   return (lval);
  362. }
  363.  
  364. /* --- following code and data does key schedule generation --- */
  365.  
  366. #define SUCCESS 0       /* return codes for ksmake */
  367. #define FAILURE SUCCESS + 1
  368.  
  369. int ksmake (inkey,ks)       /* Make a key schedule from key bytes in inkey */
  370. unsigned inkey [8];
  371. unsigned ks [16] [4];
  372. {
  373.   extern long pc2otab [8] [128];
  374.  
  375.   int   round;
  376.   long  pcct, pcdt;
  377.   long  pc2out [2];
  378.   int   i, j, parac;
  379.   unsigned incopy;
  380.  
  381.   /* test parity of bytes in inkey */
  382.   for (i = 0; i < 8; i++)       /* do each byte */
  383.   {
  384.     parac = 0;
  385.     incopy = inkey [i];
  386.  
  387.     for (j = 0; j < 8; j++)     /* 8 bits in a DES byte */
  388.     {
  389.       if (incopy & 01) parac++;
  390.       incopy >>= 1;
  391.     }
  392.     if (! (parac & 01)) return (FAILURE); /* no odd parity on this byte */
  393.   }
  394.  
  395.   /* do pc-1 permutation, extracting bits from inkey */
  396.   pcct = pcdt = 0L;
  397.   for (i = 0; i < 27; i++)   
  398.    /* filling all appropriate bits */
  399.   {
  400.     pcct |= g_keybit(pc1c [i]);
  401.     pcdt |= g_keybit(pc1d [i]);
  402.     pcct <<= 1;
  403.     pcdt <<= 1;
  404.   }
  405.   /* one final ior, without a shift */
  406.   pcct |= g_keybit(pc1c [i]);
  407.   pcdt |= g_keybit(pc1d [i]);
  408.  
  409.   for (round = 0; round < 16; round++)
  410.   {
  411.     /* always at least one shift */
  412.     pcct = lrot28 (pcct);
  413.     pcdt = lrot28 (pcdt);
  414.  
  415.     if (shiftsked [round] == 2)
  416.     {   /* this round needs another shift */
  417.       pcct = lrot28 (pcct);
  418.       pcdt = lrot28 (pcdt);
  419.     } 
  420.  
  421.     /* Now, pcct and pcdt have the values on which we can apply
  422.        pc2 and select the key bits, storing them in pc2out[0] and
  423.        pc2out[1]. The high order [pc2out[0]] bits all come from
  424.        pcct, and the low order from pcdt. */
  425.  
  426.     pc2out [0] = pc2otab [0] [pcct >> 21];
  427.     pc2out [0] |= pc2otab [1] [0X7F & (pcct >> 14)];
  428.     pc2out [0] |= pc2otab [2] [0X7F & (pcct >> 7)];
  429.     pc2out [0] |= pc2otab [3] [0X7F & pcct];
  430.  
  431.     pc2out [1] = pc2otab [4] [pcdt >> 21];
  432.     pc2out [1] |= pc2otab [5] [0X7F & (pcdt >> 14)];
  433.     pc2out [1] |= pc2otab [6] [0X7F & (pcdt >> 7)];
  434.     pc2out [1] |= pc2otab [7] [0X7F & pcdt];
  435.  
  436.     /* order key bits and bytes so as to be compatible with
  437.        the format generated by the E implementation */
  438.  
  439.     ks [round] [0] = 0XFC00 & (pc2out [0] >> 8);
  440.     ks [round] [0] |= (0XFC & (pc2out [0] >> 4));
  441.     ks [round] [1] = 0XFC00 & (pc2out [1] >> 8);
  442.     ks [round] [1] |= (0XFC & (pc2out [1] >> 4));
  443.  
  444.     ks [round] [2] = 0XFC00 & (pc2out [0] >> 2);
  445.     ks [round] [2] |= (0XFC & (pc2out [0] << 2));
  446.     ks [round] [3] = 0XFC00 & (pc2out [1] >> 2);
  447.     ks [round] [3] |= (0XFC & (pc2out [1] << 2));
  448.   }
  449.   return (SUCCESS);
  450. }
  451.  
  452. #define LMASK    0XFCFCFCFCL;
  453.  
  454. /* doip -- permute 64 bits from inar to outar */
  455. doip (inar, outar)      
  456. long    inar [2];
  457. long    outar [2];
  458. {
  459.   long lt;
  460.  
  461.   outar [0] = inar [0];
  462.   outar [1] = inar [1];
  463.   EXSHMSK(outar[1],0x0f0f0f0f,outar[0],4,lt);
  464.   EXSHMSK(outar[1],0x0000ffff,outar[0],16,lt);
  465.   EXSHMSK(outar[0],0x33333333,outar[1],2,lt);
  466.   EXSHMSK(outar[0],0x00ff00ff,outar[1],8,lt);
  467.   EXSHMSK(outar[1],0x55555555,outar[0],1,lt);
  468. }
  469.  
  470. /* doipi -- perform ip-inverse */
  471. doipi (inar, outar)     
  472. long    inar [2];
  473. long    outar [2];
  474. {
  475.   long lt;
  476.  
  477.   outar [0] = inar [0];
  478.   outar [1] = inar [1];
  479.   EXSHMSK(outar[1],0x55555555,outar[0],1,lt);
  480.   EXSHMSK(outar[0],0x00ff00ff,outar[1],8,lt);
  481.   EXSHMSK(outar[0],0x33333333,outar[1],2,lt);
  482.   EXSHMSK(outar[1],0x0000ffff,outar[0],16,lt);
  483.   EXSHMSK(outar[1],0x0f0f0f0f,outar[0],4,lt);
  484. }
  485.  
  486. /* des_encrypt -- encrypt a block under key sched in ks */
  487. des_encrypt (inar, outar, ks)   
  488. long    inar [2];
  489. long    outar [2];
  490. unsigned        ks [16] [4];
  491. {
  492.   extern long snop [8] [64];
  493.  
  494.   register int round, oddbit;
  495.   unsigned expan [4];   /* receives output of E transform */
  496.   long sbout, scopy, tlong;
  497.   long oarr [2];
  498.  
  499.   doip (inar, outar);
  500.  
  501.   for (round = 0; round < 16; round++)
  502.   {
  503.     sbout = 0L;
  504.  
  505.     tlong = outar [1];
  506.     oddbit = (int) (01 & tlong);
  507.     tlong >>= 1;
  508.     tlong &= 0X7FFFFFFFL;       /* defeat sign extend -- jl 17 feb 84 */
  509.     if (oddbit) tlong |= 0X80000000L;
  510.  
  511.     tlong &= LMASK;
  512.     expan [0] = (unsigned) (tlong >> 16);
  513.     expan [1] = (unsigned) tlong;
  514.  
  515.     tlong = outar [1];
  516.     oddbit = !! (tlong & 0X80000000L);
  517.     tlong <<= 3;
  518.     if (oddbit) tlong |= 04;
  519.     tlong &= LMASK;
  520.     expan [2] = (unsigned) (tlong >> 16);
  521.     expan [3] = (unsigned) tlong;
  522.  
  523.     /* this code bypasses the alternative of loop setup 
  524.        and resultant computation within the loop for speed */
  525.     expan [0] ^= ks [round] [0];
  526.     sbout |= snop [0] [0X3F & (expan [0] >> 10)];
  527.     sbout |= snop [1] [0X3F & (expan [0] >> 2)];
  528.     expan [1] ^= ks [round] [1];
  529.     sbout |= snop [2] [0X3F & (expan [1] >> 10)];
  530.     sbout |= snop [3] [0X3F & (expan [1] >> 2)];
  531.     expan [2] ^= ks [round] [2];
  532.     sbout |= snop [4] [0X3F & (expan [2] >> 10)];
  533.     sbout |= snop [5] [0X3F & (expan [2] >> 2)];
  534.     expan [3] ^= ks [round] [3];
  535.     sbout |= snop [6] [0X3F & (expan [3] >> 10)];
  536.     sbout |= snop [7] [0X3F & (expan [3] >> 2)];
  537.  
  538.     scopy = outar [0];
  539.     outar [0] = outar [1];
  540.     outar [1] = scopy ^ sbout;
  541.   }
  542.  
  543.   /* a final swap */
  544.   scopy = outar [0];
  545.   outar [0] = outar [1];
  546.   outar [1] = scopy;
  547.  
  548.   doipi (outar, oarr);  /* perform ip-inverse into temp copy */
  549.   outar [0] = oarr [0];
  550.   outar [1] = oarr [1];
  551. }
  552.  
  553. /* des_decrypt -- decrypt a block under key sched in ks */
  554. /* not used as of 5 May, but retained for completeness */
  555.  
  556. des_decrypt (inar, outar, ks)   
  557. long    inar [2];
  558. long    outar [2];
  559. unsigned ks [16] [4];
  560. {
  561.   extern long snop [8] [64];
  562.  
  563.   register int round, oddbit;
  564.   unsigned expan [4];   /* receives output of E transform */
  565.   long sbout, scopy, tlong;
  566.   long oarr [2];
  567.  
  568.   doip (inar, outar);
  569.  
  570.   for (round = 15; round >= 0; round--)
  571.   /* note that decryption selects schedule keys in opposite order */
  572.   {
  573.     sbout = 0L;
  574.  
  575.     tlong = outar [1];
  576.     oddbit = (int) (01 & tlong);
  577.     tlong >>= 1;
  578.     tlong &= 0X7FFFFFFFL;       /* defeat sign extend -- jl 17 feb 84 */
  579.     if (oddbit) tlong |= 0X80000000L;
  580.  
  581.     tlong &= LMASK;
  582.     expan [0] = (unsigned) (tlong >> 16);
  583.     expan [1] = (unsigned) tlong;
  584.  
  585.     tlong = outar [1];
  586.     oddbit = !! (tlong & 0X80000000L);
  587.     tlong <<= 3;
  588.     if (oddbit) tlong |= 04;
  589.     tlong &= LMASK;
  590.     expan [2] = (unsigned) (tlong >> 16);
  591.     expan [3] = (unsigned) tlong;
  592.  
  593.     /* this code bypasses the alternative of loop setup 
  594.        and resultant computation within the loop for speed */
  595.     expan [0] ^= ks [round] [0];
  596.     sbout |= snop [0] [0X3F & (expan [0] >> 10)];
  597.     sbout |= snop [1] [0X3F & (expan [0] >> 2)];
  598.     expan [1] ^= ks [round] [1];
  599.     sbout |= snop [2] [0X3F & (expan [1] >> 10)];
  600.     sbout |= snop [3] [0X3F & (expan [1] >> 2)];
  601.     expan [2] ^= ks [round] [2];
  602.     sbout |= snop [4] [0X3F & (expan [2] >> 10)];
  603.     sbout |= snop [5] [0X3F & (expan [2] >> 2)];
  604.     expan [3] ^= ks [round] [3];
  605.     sbout |= snop [6] [0X3F & (expan [3] >> 10)];
  606.     sbout |= snop [7] [0X3F & (expan [3] >> 2)];
  607.  
  608.     scopy = outar [0];
  609.     outar [0] = outar [1];
  610.     outar [1] = scopy ^ sbout;
  611.   }
  612.  
  613.   /* a final swap */
  614.   scopy = outar [0];
  615.   outar [0] = outar [1];
  616.   outar [1] = scopy;
  617.  
  618.   doipi (outar, oarr);  /* perform ip-inverse into temp copy */
  619.   outar [0] = oarr [0];
  620.   outar [1] = oarr [1];
  621. }
  622. /* support routines for demodes */
  623.  
  624. /* read input bytes from stdin */
  625. int     g_inbytes (nby, buffer)     /* returns TRUE iff EOF reached */
  626. int     nby;        /* number of bytes needed at a time */
  627.             /* if insufficient, will be padded with nulls */
  628. char    buffer [];
  629. {
  630.   int   bufix;
  631.   int   getcval;
  632.  
  633.   /* init all significant bytes to null pad */
  634.   for (bufix = 0; bufix < nby; bufix++) buffer[bufix] = 0;
  635.  
  636.   for (bufix = 0; bufix < nby; bufix++)
  637.   {
  638.     getcval = getchar ();
  639.     buffer [bufix] = (char) getcval;
  640.     if (getcval == EOF)
  641.     {
  642.       buffer[bufix] = 0;        /* replace with pad */
  643.       return (TRUE);            /* indicating that EOF detected */
  644.     }
  645.   }
  646.   return (FALSE);       /* indicating no EOF detected */
  647. }
  648.  
  649. /* represent a series of bytes (conditionally) in two buffers, as
  650.    printable representation and hex representation */
  651. di_bytes (nby, inbuf, pr_buf, hx_buf)
  652. int     nby;
  653. char    inbuf [];
  654. char    pr_buf [];      /* NULL if not desired */
  655. char    hx_buf [];      /* NULL if not desired */
  656. {
  657.   int i;
  658.  
  659.   for (i = 0; i < nby; i++)
  660.   {
  661.     if (pr_buf != NULL)
  662.     {
  663.       /* Try to show as a printable character, either directly or */
  664.       /* by masking off the MSB (if the latter, prefix with '#') */
  665.       if (inbuf [i] > 0x7f)
  666.       {
  667.     if (isprint (inbuf [i] & 0x7f))
  668.       sprintf (pr_buf, "#%c", inbuf [i] & 0x7f);
  669.     else sprintf (pr_buf, "  ");
  670.       }
  671.       else
  672.       {
  673.     if (isprint (inbuf [i]))
  674.       sprintf (pr_buf, " %c", inbuf [i]);
  675.     else sprintf (pr_buf, "  ");
  676.       }
  677.       pr_buf += 2;
  678.     }
  679.     if (hx_buf != NULL)
  680.     {
  681.       sprintf (hx_buf, "%1x%1x", 0xf & (inbuf[i]>>4),0xf & inbuf [i]);
  682.       hx_buf += 2;
  683.     }
  684.   }
  685.   if (pr_buf != NULL) sprintf (pr_buf, "|");
  686.   if (hx_buf != NULL) sprintf (hx_buf, "|");
  687. }
  688.  
  689. packbtol (as_ba, as_l)   /* pack 4 bytes into a long */
  690. char    as_ba [];
  691. long    *as_l;
  692. {
  693.   long lt;
  694.  
  695.   lt = as_ba [0] & 0xff;
  696.   lt <<= 8;
  697.   lt |= as_ba [1] & 0xff;
  698.   lt <<= 8;
  699.   lt |= as_ba [2] & 0xff;
  700.   lt <<= 8;
  701.   lt |= as_ba [3] & 0xff;
  702.  
  703.   *as_l = lt;
  704. }
  705.  
  706. sprdltob (as_l, as_ba)  /* spread a long into 4 bytes */
  707. long    as_l;
  708. char    as_ba [];
  709. {
  710.   as_ba [0] = (char) ((as_l >> 24) & 0xff);
  711.   as_ba [1] = (char) ((as_l >> 16) & 0xff);
  712.   as_ba [2] = (char) ((as_l >> 8) & 0xff);
  713.   as_ba [3] = (char) (as_l & 0xff);
  714. }
  715.  
  716. lsh64 (lar, count)      /* left shift a 64-bit quantity maintained */
  717. long    lar[];          /* in a 2-element long array. Assumes that */
  718. int     count;          /* a long has at least 32 bits */
  719. {
  720.   int   i; 
  721.   long  t;
  722.  
  723.   for (i = 0; i < count; i++)
  724.   {
  725.     t = (lar [1] >> 31) & 0x1l;
  726.     lar [1] <<= 1;
  727.     lar [0] <<= 1;
  728.     lar [0] |= t;
  729.   }  
  730.   lar [0] &= 0xffffffffl;
  731.   lar [1] &= 0xffffffffl;
  732. }
  733.  
  734. rsh64 (lar, count)      /* right shift a 64-bit quantity maintained */
  735. long    lar[];          /* in a 2-element long array. Assumes that */
  736. int     count;          /* a long has at least 32 bits */
  737. {
  738.   int   i; 
  739.   long  t;
  740.  
  741.   for (i = 0; i < count; i++)
  742.   {
  743.     t = lar [0] & 0x1l;
  744.     lar [1] >>= 1;
  745.     lar [0] >>= 1;
  746.     lar [1] |= (t << 31);
  747.   }  
  748. }
  749.  
  750. rplr64 (base, modr, nbits)      /* replace rightmost nbits of base */
  751. long    base[];                 /* (64-bit qty in 2-elmt long array) */
  752. long    modr[];                 /* with corresponding bits from modr */
  753. int     nbits;
  754. {       /* works on architectures where a long is 32 bits or more */
  755.   long  mask;
  756.   long  lmod;   /* local copy of modr word */
  757.  
  758.   mask = (nbits >= 32) ? 0xffffffffl : ((0x1l << nbits) - 1);
  759. /*  mask = (0x1l << ((nbits > 32) ? 32 : nbits)) - 1; */
  760.   base [1] &= ~mask;    /* wipe out existing low bits */
  761.   lmod = modr [1] & mask;
  762.   base [1] |= lmod;
  763.  
  764.   nbits -= 32;
  765.   if (nbits <= 0) return;
  766.   
  767.   mask = (0x1l << nbits) - 1;
  768.   base [0] &= ~mask;
  769.   lmod = modr [0] & mask;
  770.   base [0] |= lmod;
  771. }
  772.  
  773. cpy64 (src, dest)       /* copy src 2-elmt long array to dest */
  774. long    src[];
  775. long    dest[];
  776. {
  777.   dest [0] = src [0];
  778.   dest [1] = src [1];
  779. }
  780.  
  781. #ifndef TIMEONLY
  782. main (argc,argv)
  783. int     argc;
  784. char    *argv [];
  785. {
  786.   int   argn;
  787.   int   dmode;
  788.   int   eofyet = FALSE; /* will set to TRUE when end of input */
  789.   int   quant = 0;      /* quantum size (in bits) for selected mode */
  790.   int   flwid;          /* size to display a 64-bit chunk of pt or ct */
  791.   int   i, j;
  792.   long  iv [2], keyl [2];
  793.  
  794.   unsigned      inkey [8];
  795.   char  inkeyc [8]; 
  796.   char  inbbuf [8], otbbuf [8];
  797.   char  iprline [80], ihxline [80], ohxline [80];
  798.   unsigned      ks [16] [4];
  799.  
  800.   long plain [2], crypt [2], cprbuf [2], cipher [2];
  801.  
  802.   /* default key and IV to NBS sample values */
  803.   keyl [0] = 0x01234567l;
  804.   keyl [1] = 0x89abcdefl;
  805.   iv [0] = 0x12345678l;
  806.   iv [1] = 0x90abcdefl;
  807.  
  808.   /* scan the command line */
  809.   for (argn = 1; argn <= argc; argn++)
  810.   {
  811.     if (seq_nocase (argv[argn], "-m")) /* mode specifier */
  812.     {  /* one string argument expected */
  813.       argn++;
  814.       if (seq_nocase (argv[argn], "ecb")) 
  815.       {
  816.         dmode = ECB; quant = 64;
  817.       }
  818.       else if (seq_nocase (argv[argn], "cbc")) 
  819.       {
  820.         dmode = CBC; quant = 64;
  821.       }
  822.       else if (seq_nocase (argv[argn], "ofb")) 
  823.       {
  824.         dmode = OFB; if (quant == 0) quant = 64; /* may be overridden */
  825.       }
  826.       else if (seq_nocase (argv[argn], "cfb")) 
  827.       {
  828.         dmode = CFB; if (quant == 0) quant = 64; /* may be overridden */
  829.       }
  830.     }
  831.     else if (seq_nocase (argv[argn], "-k"))    /* key specifier */
  832.     {  /* two long hex numerics expected */
  833.       argn++;
  834.       sscanf (argv[argn], "%lx", &keyl [0]);
  835.       argn++;
  836.       sscanf (argv[argn], "%lx", &keyl [1]);
  837.     }
  838.     else if (seq_nocase (argv[argn], "-iv"))   /* IV specifier */
  839.     {  /* two long hex numerics expected */
  840.       argn++;
  841.       sscanf (argv[argn], "%lx", &iv [0]);
  842.       argn++;
  843.       sscanf (argv[argn], "%lx", &iv [1]);
  844.     }
  845.     else if (seq_nocase (argv[argn], "-q"))     /* quantum specifier */
  846.     { /* one decimal number expected */
  847.       argn++;
  848.       sscanf (argv[argn], "%d", &quant);
  849.     }
  850.   }
  851.  
  852.   if (((dmode == ECB) || (dmode == CBC)) && (quant != 64))
  853.   {
  854.     printf ("Can't override quantum of 64 for ECB or CBC modes... aborting\n");
  855.     exit (1);
  856.   }
  857.  
  858.   /* build key schedule (outside scanner, so default works) */
  859.   sprdltob (keyl [0], & inkeyc [0]);
  860.   sprdltob (keyl [1], & inkeyc [4]);
  861.   for (i = 0; i < 8; i++) inkey [i] = (unsigned) (inkeyc [i] & 0xff);
  862.   if (ksmake (inkey, ks) != SUCCESS)
  863.   {
  864.     printf ("Bad parity on key... aborting...\n");
  865.     exit (1);
  866.   }
  867.  
  868.   printf ("Mode is ");
  869.   switch (dmode)
  870.   {
  871.     case ECB:
  872.       printf ("ECB;");
  873.       break;
  874.     case CBC:
  875.       printf ("CBC;");
  876.       break;
  877.     case OFB:
  878.       printf ("OFB;");
  879.       printf (" Quantum is %d;", quant);
  880.       break;
  881.     case CFB:
  882.       printf ("CFB;");
  883.       printf (" Quantum is %d;", quant);
  884.       break;
  885.     default:
  886.       printf ("Unknown;");
  887.       break;
  888.   }
  889.   printf (" Key is %lx %lx;", keyl [0], keyl [1]);
  890.   if (dmode != ECB) printf (" IV is %lx %lx;", iv [0], iv [1]);
  891.   printf ("\n");
  892.  
  893.   flwid = (8 * 2) + 1;      /* 8 bytes, 2 chars/byte, and a delimiter */
  894.  
  895.   while (eofyet == FALSE)       /* until EOF detected on input */
  896.   {
  897.     if (dmode == ECB)
  898.     {
  899.       for (i = 0; i < 4; i++)     /* 4 groups on a printable line */
  900.       {
  901.         if (TRUE == g_inbytes (8, inbbuf)) eofyet = TRUE;
  902.         di_bytes (8, inbbuf, &iprline [flwid*i], &ihxline [flwid*i]);
  903.         packbtol (&inbbuf[0], &plain[0]);
  904.         packbtol (&inbbuf[4], &plain[1]);
  905.         des_encrypt (plain, crypt, ks);
  906.         sprdltob (crypt[0], &otbbuf[0]);
  907.         sprdltob (crypt[1], &otbbuf[4]);
  908.         di_bytes (8, otbbuf, NULL, &ohxline [flwid*i]);
  909.     if (TRUE == eofyet) break;
  910.       }
  911.     }
  912.     else if (dmode == CBC)
  913.     {
  914.       for (i = 0; i < 4; i++)     /* 4 groups on a printable line */
  915.       {
  916.         if (TRUE == g_inbytes (8, inbbuf)) eofyet = TRUE;
  917.         di_bytes (8, inbbuf, &iprline [flwid*i], &ihxline [flwid*i]);
  918.         packbtol (&inbbuf[0], &plain[0]);
  919.         packbtol (&inbbuf[4], &plain[1]);
  920.     plain [0] ^= iv [0];    /* XOR IV with input plaintext */
  921.         plain [1] ^= iv [1];
  922.         des_encrypt (plain, crypt, ks);
  923.         sprdltob (crypt[0], &otbbuf[0]);
  924.         sprdltob (crypt[1], &otbbuf[4]);
  925.         di_bytes (8, otbbuf, NULL, &ohxline [flwid*i]);
  926.     iv [0] = crypt [0];     /* use ciphertext output as next IV */
  927.         iv [1] = crypt [1];
  928.     if (TRUE == eofyet) break;
  929.       }
  930.     }
  931.     else if (dmode == CFB)
  932.     {
  933.       for (i = 0; i < 4; i++)     /* 4 groups on a printable line */
  934.       /* does file read and display in 64-bit units regardless of quantum */
  935.       {
  936.         if (TRUE == g_inbytes (8, inbbuf)) eofyet = TRUE;
  937.         di_bytes (8, inbbuf, &iprline [flwid*i], &ihxline [flwid*i]);
  938.         packbtol (&inbbuf[0], &plain[0]);
  939.         packbtol (&inbbuf[4], &plain[1]);
  940.     for (j = 0; j < 64; j+=quant)
  941.     {
  942.           des_encrypt (iv, crypt, ks);
  943.       rsh64 (crypt, 64-quant);      /* right-align active DES output bits */
  944.       cpy64 (plain, cprbuf);        /* copy plaintext to scratch */
  945.       rsh64 (cprbuf, 64-(quant+j)); /* right-align active plaintext bits */
  946.       /* XOR them into DES output */
  947.       crypt [0] ^= cprbuf [0];  crypt [1] ^= cprbuf [1];
  948.       lsh64 (iv, quant);            /* shift existing IV over */
  949.       rplr64 (iv, crypt, quant);    /* replace LS IV bits with DES output */
  950.       lsh64 (cipher, quant);        /* make space in cipher out array */
  951.       rplr64 (cipher, crypt, quant); /* insert new output bits */
  952.     }
  953.         sprdltob (cipher[0], &otbbuf[0]);
  954.         sprdltob (cipher[1], &otbbuf[4]);
  955.         di_bytes (8, otbbuf, NULL, &ohxline [flwid*i]);
  956.     if (TRUE == eofyet) break;
  957.       }
  958.     }
  959.     else if (dmode == OFB)
  960.     {
  961.       for (i = 0; i < 4; i++)     /* 4 groups on a printable line */
  962.       {
  963.         if (TRUE == g_inbytes (8, inbbuf)) eofyet = TRUE;
  964.         di_bytes (8, inbbuf, &iprline [flwid*i], &ihxline [flwid*i]);
  965.         packbtol (&inbbuf[0], &plain[0]);
  966.         packbtol (&inbbuf[4], &plain[1]);
  967.     for (j = 0; j < 64; j+=quant)
  968.     {
  969.           des_encrypt (iv, crypt, ks);
  970.       rsh64 (crypt, 64-quant);      /* right-align active DES output bits */
  971.       lsh64 (iv, quant);            /* shift existing IV over */
  972.       rplr64 (iv, crypt, quant);    /* replace LS IV bits with DES output */
  973.       cpy64 (plain, cprbuf);        /* copy plaintext to scratch */
  974.       rsh64 (cprbuf, 64-(quant+j)); /* right-align active plaintext bits */
  975.       /* XOR them into DES output */
  976.       crypt [0] ^= cprbuf [0];  crypt [1] ^= cprbuf [1];
  977.       lsh64 (cipher, quant);        /* make space in cipher out array */
  978.       rplr64 (cipher, crypt, quant); /* insert new output bits */
  979.     }
  980.         sprdltob (cipher[0], &otbbuf[0]);
  981.         sprdltob (cipher[1], &otbbuf[4]);
  982.     di_bytes (8, otbbuf, NULL, &ohxline [flwid*i]);
  983.         if (TRUE == eofyet) break;
  984.       }                      
  985.     }
  986.     printf ("%s\n%s\n%s\n", iprline, ihxline, ohxline);
  987.   }
  988.   printf ("\n");
  989. }
  990. #endif
  991.  
  992. #ifdef  TIMEONLY
  993. main ()
  994. {
  995.   int itnum, i;
  996.   long plain [2], crypt [2], cprbuf [2];
  997.   long udiff, bitsdone, u_msec;
  998.   unsigned ks [16] [4];
  999.   long keyl [2];
  1000.   unsigned inkey [8];
  1001.   char  inkeyc [8]; 
  1002.  
  1003.   /* default key to NBS sample value */
  1004.   keyl [0] = 0x01234567l;
  1005.   keyl [1] = 0x89abcdefl;
  1006.   /* build key schedule (outside scanner, so default works) */
  1007.   sprdltob (keyl [0], & inkeyc [0]);
  1008.   sprdltob (keyl [1], & inkeyc [4]);
  1009.   for (i = 0; i < 8; i++) inkey [i] = (unsigned) (inkeyc [i] & 0xff);
  1010.   if (ksmake (inkey, ks) != SUCCESS)
  1011.   {
  1012.     printf ("Bad parity on key... aborting...\n");
  1013.     exit (1);
  1014.   }
  1015.  
  1016.   printf ("Enter number of test iterations [decimal]: ");
  1017.   scanf ("%d", &itnum);
  1018.  
  1019.   times (&t_before);
  1020.   for (i = 0; i < itnum; i++)   
  1021.   {
  1022.     des_encrypt (plain, crypt, ks);
  1023.     des_decrypt (crypt, cprbuf, ks);
  1024.     if ((plain [0] != cprbuf [0]) || (plain [1] != cprbuf [1]))
  1025.     {
  1026.       printf ("Encrypt and decrypt disagree -- aborting!!\n");
  1027.       exit (1);
  1028.     }
  1029.   }
  1030.   times (&t_after);
  1031.   printf ("All encryptions and decryptions verified consistent\n");
  1032.  
  1033.   /* note: the following code won't work if one times a number
  1034.      of encryptions that take less than one tick, as can occur
  1035.      on a vax with a small number of tests */
  1036.   udiff = t_after.proc_utime - t_before.proc_utime;
  1037.   printf ("user 1/60 sec ticks = %ld\n", udiff);
  1038.   bitsdone = 2 * (itnum * 64);
  1039.   u_msec = (udiff * 1000) / 60;
  1040.   printf ("%ld user msec/DES cycle\n", u_msec / ((long) 2 * itnum));
  1041.   printf ("%ld bits/user second\n", (bitsdone * 1000) / u_msec);
  1042. }
  1043. #endif
  1044.